/* Finite State Machine
*/

#ifndef FSM_H
#define FSM_H

#include <stdlib.h>   // for rand, itoa
#include <stdio.h>
#include <string.h>
#include <ctype.h>    // for tolower
#include <assert.h>   // for assert
#include <sys/time.h> // timer
#include <signal.h>   // timer
#include <time.h>     // itimerspec


#include "packet.h"

#define WAITING 0
#define OPEN 1
#define PLAYING 2

#define MSG_SETUP "setup"
#include <sys/types.h> // for send
#include <sys/socket.h> // for send


#define MSG_PLAY "play"
#define MSG_PAUSE "pause"
#define MSG_TEARDOWN "teardown"
#define MSG_SCALE "scale"

#define NUMERIC "1234567890"
#define INTERVAL_NS 40000000 // 40 ms in ns

typedef struct sigevent sig_event_t;
typedef struct itimerspec itimerspec_t;

// This struct is created to save information that will be needed by the timer,
// such as socket file descriptors, frame numbers and video captures.
typedef struct {
  int socket_fd;
  int scale;
  char* filename;
  int frame_num;
  server_list* s_list;
} send_frame_data;

// this struct holds information about the client's session with the server
typedef struct{

    int socket_fd;
	int session;
	int cseq;
    int state;
	int error;

    send_frame_data* data;       // data used by timer & cv

	sig_event_t *play_event;     // for timer
    itimerspec_t *play_interval; // for timer
    timer_t *play_timer;         // for timer

    video_manager *cv;           // for getting frame from video

} stream_state;

void init_stream_state(stream_state* stream, int socket);

void handle_client_request(stream_state* stream, int request_length, char* request, char* out_buf);
int check_syntax_error(stream_state* stream, char* commd_buf, char* cseq_buf, char* scale_buf, char* session_buf); // return err num
char read_request(stream_state* stream, int request_length, char* request); // return 1 for OK, 0 for error
void get_response(stream_state* stream, char* response_buffer);

void send_frame(union sigval sv_data);

#endif
